/**
 * 
 */
package org.youisoft.summer.evaluator.function.ext;

import org.youisoft.summer.evaluator.context.CalContext;
import org.youisoft.summer.evaluator.function.AbstractFunction;
import org.youisoft.summer.evaluator.operator.Operator;
import org.youisoft.summer.evaluator.operator.base.ListOperator;
import org.youisoft.summer.evaluator.operator.base.NumberOperator;

/**
 * @author zijiang.jl
 *
 */
public class MaxFunction extends AbstractFunction {
	private static final java.util.List<Class<?>> supports;
	static{
		supports=new java.util.ArrayList<Class<?>>();
		supports.add(ListOperator.class);
		supports.add(NumberOperator.class);
	}


	@Override
	public String getName() {
		return "max";
	}

	@Override
	protected boolean checkOperator(int index, Operator<?> operator) {
		return supports.contains(operator.getClass());
	}

	@Override
	public <C,R,P> Operator<?> doInvoke(CalContext<C,R,P> context,Operator<?>... operator) {
		NumberOperator max=new NumberOperator();
		for(int i=0;i<operator.length;i++){
			if(operator[i] instanceof NumberOperator) {
				NumberOperator temp=NumberOperator.class.cast(operator[i]);
				if(max.value()==null||temp.value().doubleValue()>max.value().doubleValue()){
					max.setValue(temp.value());
				}
			}else if(operator[i] instanceof ListOperator<?>){
				this.maxList(max, (ListOperator<?>)operator[i]);
			}
		}
		return max;
	}
	
	
	private void maxList(NumberOperator max,ListOperator<?> dlo){
		for(int j=0;j<dlo.size();j++){
			if(dlo.getOperator(j) instanceof NumberOperator){
				NumberOperator temp=NumberOperator.class.cast(dlo.getOperator(j));
				if(max.value()==null||temp.value().doubleValue()>max.value().doubleValue()){
					max.setValue(temp.value());
				}
			}
			if(dlo.getOperator(j) instanceof ListOperator<?>){
				this.maxList(max, (ListOperator<?>)dlo.getOperator(j));
			}
			
		}
	}
	
	@Override
	protected int minOperatorCount() {
		return 1;
	}
	
}
